package com.hongji.lms5xxcommunicator.realtime.websoket;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Slf4j
@Component("springWsBroadcaster")
public class SpringWsBroadcaster implements WsBroadcaster {

    private final StreamHub hub;
    private final ObjectMapper om = new ObjectMapper();

    // ★ 用于收集“正在构建中的整帧”
    private volatile long buildingSeq = -1L;
    private final List<String> buildingChunks = new ArrayList<>();

    public SpringWsBroadcaster(StreamHub hub) {
        this.hub = hub;
    }

    @Override
    public synchronized void broadcast(Object dto) {
        try {
            String json = (dto instanceof String) ? (String) dto : om.writeValueAsString(dto);

            try {
                JsonNode node = om.readTree(json);

                // (A) gridSpec：缓存规格（用于新连接先画画布）
                if (node.has("gridSpec")) {
                    hub.setLastGridSpecJson(json);
                    log.debug("[ws] 检测到 gridSpec，已更新 lastGridSpecJson");
                }

                // (B) 分片信息：seq/chunk/chunks（用于整帧收集）
                long seq  = node.has("seq")   ? node.get("seq").asLong(-1L)   : -1L;
                int  chunk= node.has("chunk") ? node.get("chunk").asInt(-1)   : -1;
                int  chunksTotal = node.has("chunks") ? node.get("chunks").asInt(-1) : -1;
                boolean isFullStart = node.has("full") && node.get("full").asBoolean(false);

                if (seq > 0 && chunk > 0 && chunksTotal > 0) {
                    // 帧起始（full=true 的第一片）：重置收集器
                    if (isFullStart) {
                        buildingSeq = seq;
                        buildingChunks.clear();
                    }
                    // 只收集当前正在构建的那一帧
                    if (seq == buildingSeq && buildingSeq > 0) {
                        buildingChunks.add(json);
                        // 帧结束：把整帧写入 StreamHub（一个不可变副本）
                        if (chunk == chunksTotal) {
                            hub.setLastFullFrameChunks(Collections.unmodifiableList(new ArrayList<>(buildingChunks)));
                            // 兼容：首片内容也存入单帧字段（老前端/兜底）
                            hub.setLastFullFrameJson(buildingChunks.isEmpty() ? null : buildingChunks.get(0));
                            log.debug("[ws] 整帧缓存完成：seq={}, chunks={}", buildingSeq, buildingChunks.size());
                            buildingSeq = -1L;
                            buildingChunks.clear();
                        }
                    }
                } else {
                    // 没有分片信息的旧消息：如果是 full 帧，就至少缓存首片
                    if (isFullStart) {
                        hub.setLastFullFrameJson(json);
                        log.debug("[ws] 检测到 full 帧（无分片信息），已更新 lastFullFrameJson");
                    }
                }
            } catch (Exception e) {
                log.warn("[ws] JSON 解析失败（忽略，不影响广播）：{}", e.getMessage());
            }

            // 真正广播给在线会话
            hub.broadcast(json);
            log.info("[ws] 广播成功：长度={}，内容预览={}",
                    json.length(),
                    json.length() > 200 ? json.substring(0, 200) + "..." : json);

        } catch (Exception e) {
            log.error("[ws] 广播异常：{}", e.getMessage(), e);
        }
    }
}
